home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 26 / Cream of the Crop 26.iso / os2 / pvm34b3.zip / pvm34b3 / pvm3 / gexamples / trsg.c < prev    next >
C/C++ Source or Header  |  1997-07-22  |  7KB  |  225 lines

  1.  
  2. static char rcsid[] =
  3.     "$Id: trsg.c,v 1.2 1997/07/09 13:28:06 pvmsrc Exp $";
  4.  
  5. /*
  6.  *         PVM version 3.4:  Parallel Virtual Machine System
  7.  *               University of Tennessee, Knoxville TN.
  8.  *           Oak Ridge National Laboratory, Oak Ridge TN.
  9.  *                   Emory University, Atlanta GA.
  10.  *      Authors:  J. J. Dongarra, G. E. Fagg, M. Fischer
  11.  *          G. A. Geist, J. A. Kohl, R. J. Manchek, P. Mucci,
  12.  *         P. M. Papadopoulos, S. L. Scott, and V. S. Sunderam
  13.  *                   (C) 1997 All Rights Reserved
  14.  *
  15.  *                              NOTICE
  16.  *
  17.  * Permission to use, copy, modify, and distribute this software and
  18.  * its documentation for any purpose and without fee is hereby granted
  19.  * provided that the above copyright notice appear in all copies and
  20.  * that both the copyright notice and this permission notice appear in
  21.  * supporting documentation.
  22.  *
  23.  * Neither the Institutions (Emory University, Oak Ridge National
  24.  * Laboratory, and University of Tennessee) nor the Authors make any
  25.  * representations about the suitability of this software for any
  26.  * purpose.  This software is provided ``as is'' without express or
  27.  * implied warranty.
  28.  *
  29.  * PVM version 3 was funded in part by the U.S. Department of Energy,
  30.  * the National Science Foundation and the State of Tennessee.
  31.  */
  32.  
  33. /*
  34.  * Example of group Reduce, Scatter, and Gather functions - J.M. Donato
  35.  * 
  36.  * This example calculates the sum of squares of the first N integers
  37.  * in three different ways where 
  38.  *
  39.  *   N = (number of processors)*(number of elements per row)
  40.  *
  41.  * Note:  This is obviously not an efficient way to compute the 
  42.  *        sum of squares, but it is a cutesy example and test case.
  43.  */
  44.  
  45. #include <stdio.h>
  46. #include "pvm3.h"
  47.  
  48. #define MAXNDATA  20
  49. #define MAXNPROCS 16
  50. #define DFLTNDATA 5
  51. #define DFLTNPROCS 4
  52. #define TASK_NAME "trsg"
  53.  
  54. #define min(x,y) ( ((x)<(y))? (x) : (y) )
  55. #define max(x,y) ( ((x)>(y))? (x) : (y) )
  56.  
  57. extern void PvmMin();
  58. extern void PvmMax();
  59. extern void PvmSum();
  60. extern void PvmProduct();
  61.  
  62. void MaxWithLoc();
  63.  
  64. main()
  65. {
  66.   int myginst, i, j, gsize, count, nprocs, msgtag, datatype; 
  67.   int info_product, info_user; 
  68.   int  tids[MAXNPROCS], myrow[MAXNDATA], matrix[MAXNDATA*MAXNPROCS]; 
  69.   float values[2];
  70.   int midpoint, bigN, Sum1=0, Sum2=0, SumSquares, rootginst; 
  71.   int PSum = 0, PartSums[MAXNPROCS], dupls[MAXNDATA];
  72.   char *gname = "group_rsg";
  73.  
  74.   /* join the group */
  75.   myginst = pvm_joingroup(gname);
  76.   pvm_setopt(PvmAutoErr, 1);
  77.  
  78.   /* I am the first group member, get input, start up copies of myself */
  79.   if ( myginst == 0 )       
  80.   {
  81.     if (pvm_parent() == PvmNoParent)
  82.     {
  83.       printf("\n *** Example use of PVM Reduce, Scatter, and Gather *** ");
  84.       printf("\n Number of processors to use (1-%d)? : ", MAXNPROCS);
  85.       scanf("%d", &nprocs);
  86.       if (nprocs > MAXNPROCS) nprocs = MAXNPROCS;
  87.       printf(" Number of elements per row to use (1-%d)? : ", MAXNDATA);
  88.       scanf("%d", &count);
  89.       if (count > MAXNDATA) count = MAXNDATA;
  90.       printf(" INPUT values: nprocs = %d, count = %d \n", nprocs, count);
  91.     }
  92.     else
  93.     {
  94.       count = DFLTNDATA;
  95.       nprocs = DFLTNPROCS;
  96.     }
  97.  
  98.     tids[0] = pvm_mytid();
  99.  
  100.     if (nprocs > 1)
  101.       pvm_spawn(TASK_NAME, (char**)0, 0, "", nprocs-1, &tids[1]);
  102.  
  103.     /* wait until they have all started, then send input values */
  104.     while (gsize = pvm_gsize(gname) < nprocs) sleep(1);
  105.     pvm_initsend(PvmDataDefault);
  106.     pvm_pkint(&nprocs, 1, 1);
  107.     pvm_pkint(&count,  1, 1);
  108.     pvm_bcast(gname, msgtag=17);
  109.   }
  110.   else
  111.   {
  112.     /* receive the input values */
  113.     pvm_recv(-1, msgtag=17);
  114.     pvm_upkint(&nprocs, 1, 1);
  115.     pvm_upkint(&count,  1, 1);
  116.   }
  117.   
  118.   rootginst = 0;  /* determine the group root */
  119.  
  120.   /* init the matrix values on the root processor */
  121.   if (myginst == rootginst) 
  122.     for (j=0; j<nprocs; j++)
  123.       for (i=0; i<count; i++)
  124.         matrix[j*count + i] = j*count + i + 1;
  125.  
  126.   /* scatter rows of matrix to each processor */
  127.   pvm_scatter(myrow, matrix, count, PVM_INT, msgtag=19, gname, rootginst);
  128.  
  129.   /* this should end up squaring each value on each processor */
  130.   for (i=0; i<count; i++) dupls[i] = (myginst*count + i + 1);
  131.   datatype = PVM_INT;
  132.   PvmProduct(&datatype, myrow, dupls, &count, &info_product);
  133.   if ((myginst == rootginst) && (info_product < 0))
  134.       printf(" ERROR: %d on PvmProduct call \n", info_product);
  135.  
  136.   /* do partial sum on each proc */
  137.   for (i=0; i<count; i++) PSum += myrow[i];
  138.  
  139.   /* gather partial sums to the rootginst */
  140.   pvm_gather(PartSums, &PSum, 1, PVM_INT, msgtag=21, gname, rootginst);
  141.  
  142.   /* do a global sum over myrow, the result goes to rootginst */
  143.   pvm_reduce(PvmSum, myrow, count, PVM_INT, msgtag=23, gname, rootginst);
  144.  
  145.   /* init values and include location information on each processor */
  146.   midpoint = nprocs/2;
  147.   values[0] = -(myginst - midpoint)*(myginst-midpoint) + count;
  148.   values[1] = myginst;    /* location information */
  149.  
  150.   /* use a user-defined function in reduce, send answer to rootginst */
  151.   info_user = pvm_reduce(MaxWithLoc, values, 2, PVM_FLOAT, 
  152.                          msgtag=25, gname, rootginst);
  153.  
  154.   bigN = nprocs*count;
  155.   if (myginst == rootginst)
  156.   {
  157.     /* Complete the Sum of Squares using different methods */
  158.     for (i=0; i<nprocs; i++) Sum1 += PartSums[i]; 
  159.     for (i=0; i<count;  i++) Sum2 += myrow[i];    
  160.     SumSquares = bigN*(bigN+1)*(2*bigN+1)/6;
  161.     if ( (Sum1 == SumSquares) && (Sum2 == SumSquares))
  162.       printf("\n Test OK: Sum of Squares of first %d integers is %d \n",
  163.              bigN, Sum1);
  164.     else
  165.       printf("\n %s%d%s%d%s%d,\n%s%d \n", 
  166.              "ERROR: The Sum of Squares of the first ", bigN, 
  167.              " integers \n was calculated by Sum1 as ", Sum1,
  168.              " and by Sum2 as ", Sum2,
  169.              " for both it should have been ", SumSquares);
  170.  
  171.     if (info_user < 0) 
  172.       printf(" ERROR: %d on Reduce with User Function\n", info_user);
  173.  
  174.     if ((values[0] != count) || (values[1] != midpoint)) 
  175.       printf(" ERROR: Should have (%f, %f), but have (%f, %f): \n",
  176.                count, midpoint, values[0], values[1]);
  177.     else
  178.       printf(" Test Ok: Received (%f, %f): ", values[0], values[1]);
  179.     printf("\n");
  180.   }
  181.  
  182.   /* sync up again, leave group, exit pvm */
  183.   pvm_barrier(gname, nprocs);   
  184.   pvm_lvgroup(gname);
  185.   pvm_exit();
  186.   exit(1);
  187.  
  188. } /* end main() */
  189.  
  190.  
  191. /*
  192.   This function returns the elementwise maximum of two vectors 
  193.   along with location information.
  194.  
  195.   The first num/2 values of x and y are the data values to compare.
  196.   The second num/2 values of x and y are location information
  197.   which is kept with the maximum value determined.
  198.  
  199.   In the case of a tie in data values, the smaller location 
  200.   is kept to insure the associativity of the operation.
  201. */
  202.  
  203. void MaxWithLoc(datatype, x, y, num, info)
  204. int *datatype, *num, *info;
  205. float *x, *y;
  206. {
  207.   int i, count;
  208.   count = (*num) / 2;
  209.  
  210.   if (*datatype != PVM_FLOAT) { *info = PvmBadParam; return; }
  211.  
  212.   for (i=0; i<count; i++)
  213.     if (y[i] > x[i])
  214.     {
  215.       x[i]       = y[i];
  216.       x[i+count] = y[i+count];
  217.     }
  218.     else
  219.       if (y[i] == x[i]) x[i+count] = min(x[i+count], y[i+count]);
  220.  
  221.   *info = PvmOk;
  222.   return;
  223.  
  224. }  /* end MaxWithLoc() */
  225.